#include "protectedmain.h"
#include <chrono>
#include <fstream>
#include <iostream>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

using SysTime = std::chrono::system_clock;

template <typename F>
auto benchmark(F&& func)
{
    auto stime = SysTime::now();
    func();
    auto etime = SysTime::now();
    return etime - stime;
}

constexpr auto size = 0x1000;

int protectedMain(int argc, char** argv) noexcept(false)
{
    (void)argc;
    (void)argv;
    {
        char buf[size]{};
        if (auto file = std::fstream("test.txt", std::ios::out))
        {
            file.write(buf, size);
        }
    }
    {
        char buf[size];
        if (auto file = std::fstream("test.txt", std::ios::in))
        {
            auto time = benchmark([&file, &buf] { file.read(buf, size); });
            std::cout << "C++ time: "
                      << std::chrono::duration_cast<std::chrono::microseconds>(
                             time)
                             .count()
                      << '\n';
        }
    }

    {
        void* buf;
        if (int fd = open("test.txt", O_RDONLY); fd != 0)
        {
            auto time = benchmark([&fd, &buf] {
                buf = ::mmap(nullptr, size, PROT_READ, 0, fd, 0);
            });
            ::munmap(buf, size);
            std::cout << "mmap time: "
                      << std::chrono::duration_cast<std::chrono::microseconds>(
                             time)
                             .count()
                      << '\n';
        }
    }
    return 0;
}